using System;
using System.Collections.Generic;
using System.Text;
using JobShopModel.Model.FactoryLvl;
using System.IO;

namespace JobShopModel.Model
{
    /// <summary>
    /// Class that is used to write output to the main form
    /// </summary>
    public class Logger
    {
        private static Logger myLogger;

        private Dictionary<ItemPriorities,List<LogItem>> logTable;
       // private List<LogItem> dump;

        private List<LogItem> lastItems;

        private bool isWritingAutomaticaly;

        private ItemPriorities defaultPriority;

        private Logger()
        {
            //Create elements
            this.logTable = new Dictionary<ItemPriorities,List<LogItem>>();
            this.lastItems = new List<LogItem>();
            //this.dump = new List<LogItem>();

            //Set the default values
            this.isWritingAutomaticaly = false;
            this.defaultPriority = ItemPriorities.NORMAL;
        }

        /// <summary>
        /// Returns the logger, or instantiates one if one does not exist
        /// </summary>
        /// <returns>Instance of a logger</returns>
        public static Logger GetLogger()
        {
            if (myLogger == null)
            {
                myLogger = new Logger();
            }
            return myLogger;
        }


        public bool IsWritingAutomaticaly
        {
            get{ return this.isWritingAutomaticaly;}
            set { this.isWritingAutomaticaly = true;}
        }

        public ItemPriorities DefaultPriority
        {
            get { return this.defaultPriority; }
            set { this.defaultPriority = value; }

        }

        /// <summary>
        /// Creates a list of messages (if one does not already exist) and inserts a message to be written
        /// </summary>
        /// <param name="message">The message to be inserted</param>
        public void InsertElement(LogItem message)
        {
            //Add the message to the list at the corresponding priority 
            //Create the list if it do not exist
            if (!logTable.ContainsKey(message.Priority))
            {
                logTable[message.Priority] = new List<LogItem>();
            }
            logTable[message.Priority].Add(message);
            
            //Add the message to the buffer list if it correspond to the level of priority
            if (message.Priority >= DefaultPriority)
            {
                lastItems.Add(message);
                //dump.Add(message);
            }

            //Write the message to file if the property is set
            if (isWritingAutomaticaly)
            {
                this.AppendToFile(message);
            }
        }

        /// <summary>
        /// Return all the element that have not been read
        /// in a time order
        /// Depending on the priority level we want
        /// </summary>
        /// <param name="minPriority"></param>
        /// <returns></returns>
        public List<LogItem> GetLastItems()
        {
            List<LogItem> rtn = new List<LogItem>(lastItems);

            //Empty the lasElement buffer (they just been read)
            lastItems.Clear();

            return rtn;
        }

        public void EmptyLogger()
        {
            this.lastItems.Clear();
            this.logTable.Clear();
        }


        public void WriteLog(string fileName,ItemPriorities minPriority)
        {
            //Sort all the good elements
            List<LogItem> listElement = new List<LogItem>();
            //Get the right priority
            foreach (ItemPriorities i in logTable.Keys)
            {
                if (i >= minPriority)
                {
                    //Get all the items
                    foreach (LogItem l in logTable[i])
                    {
                        listElement.Add(l);
                        
                    }
                }
            }

            //Open the Log file
            TextWriter writer = new StreamWriter(fileName);

            //write the items in sorted order
            listElement.Sort();
            
            foreach (LogItem l in listElement)
            {
                writer.WriteLine("[" + l.Priority + "]\t" + l.ToString());
            }
            /*
            foreach( LogItem l in dump)
            {
                writer.WriteLine("[" + l.Priority + "]\t" + l.ToString());
            }
            */
            //Close the file
            writer.Close();

        }


        private void AppendToFile(LogItem message)
        {
            //TODO: Close a more efficient way of opening/closing the file (Not at all element)
            if (message.Priority >= defaultPriority)
            {
                //Open the default Log file
                TextWriter writer = new StreamWriter(".\\Log.txt");
                
                //Write the last message
                writer.WriteLine(message);
                
                //Close the file
                writer.Close();
            }
        }
    }


    public enum ItemPriorities
    {

        SLOW = 1,
        NORMAL = 2,


        CREATION = 3,
        URGENT = 4,
           
        NONE = 5,

        STATISTICS = 6,
        
    }
}
